package org.xm.sk.controller.dbase;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.xm.sk.exception.DataNotFoundException;
import org.xm.sk.exception.RequestParamterException;
import org.xm.sk.module.IdBitWorker;
import org.xm.sk.service.data.BaseService;
import org.xm.sk.service.security.XmUser;
import org.xm.sk.vo.Base;
import org.xm.sk.vo.e.ActivityStatus;
import org.xm.sk.vo.e.CouponStatus;
import org.xm.sk.vo.e.Datalevel;
import org.xm.sk.vo.ob.CrtActivity;
import org.xm.sk.vo.ob.Ids;
import org.xm.sk.vo.ob.MapList;
import org.xm.sk.vo.ob.PageConf;
import org.xm.sk.vo.ob.ResultMsg;
import org.xm.sk.vo.tb.Activity;
import org.xm.sk.vo.tb.Brand;
import org.xm.sk.vo.tb.Coupon;
import org.xm.sk.vo.tb.Hairdresser;
import org.xm.sk.vo.tb.Image;
import org.xm.sk.vo.tb.Item;
import org.xm.sk.vo.tb.Shop;
import org.xm.sk.vo.tb.User;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@SuppressWarnings("unchecked")
@Api(tags = { "activity" })
@RestController
@RequestMapping(value="/activitys")
public class ActivityController {
    
    @Autowired
    private MessageSource messages;
    @Autowired
    private BaseService<User> userService;
    @Autowired
    private BaseService<Activity> activityService;
    @Autowired
    private BaseService<Shop> shopService;
    @Autowired
    private BaseService<Item> itemService;
    @Autowired
    private BaseService<Brand> brandService;
    @Autowired
    private BaseService<Hairdresser> hairdresserService;
    @Autowired
    private BaseService<Image> imageService;
    @Autowired
    private BaseService<Coupon> couponService;
    @Autowired
    private IdBitWorker idBitWorker;

    @ApiOperation(value="创建活动", notes="根据activity对象表单字段创建活动，使用此接口需要ADMIN权限")
    @ApiImplicitParam(name = "crtActivity", value = "优惠活动创建内容实体", required = true, dataType = "CrtActivity")
    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value="", method=RequestMethod.POST)
    public ResultMsg add(@RequestBody CrtActivity crtActivity) throws IOException {
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        User user = (User) userService.findById(xmUser.getUserid());
        if (null == user || Datalevel.NORMAL != user.getDatalevel()) {
            throw new AccessDeniedException("无效令牌信息，查无用户信息");
        }
        Activity u = null;
        if (null == crtActivity.getId() || 1 > crtActivity.getId()) {
            u = new Activity();
        } else {
            u = (Activity) activityService.findById(crtActivity.getId());
        }
        u.setStatus(ActivityStatus.NORMAL);
        u.setOrgan(user.getOrgan());
        u.setConditions(crtActivity.getConditions());
        u.setCount(crtActivity.getCount());
        u.setStartline(crtActivity.getStartline());
        u.setDeadline(crtActivity.getDeadline());
        u.getImages().clear();
        if (null != crtActivity.getImageId() && 0 < crtActivity.getImageId()) {
            Image image = (Image) imageService.findById(crtActivity.getImageId());
            if (null != image) {
                u.getImages().add(image);
            }
        }
        u.setName(crtActivity.getName());
        u.setPrice(crtActivity.getPrice());
        u.setScope(crtActivity.getScope());
        if (null != crtActivity.getShopIds()) {
            u.getShops().clear();
            for (Integer shopId : crtActivity.getShopIds()) {
                Shop s = (Shop) shopService.findById(shopId);
                if (null != s) {
                    u.getShops().add(s);
                }
            }
        }
        if (null != crtActivity.getItemIds()) {
            u.getItems().clear();
            for (Integer itemId : crtActivity.getItemIds()) {
                Item s = (Item) itemService.findById(itemId);
                if (null != s) {
                    u.getItems().add(s);
                }
            }
        }
        if (null != crtActivity.getBrandIds()) {
            u.getBrands().clear();
            for (Integer brandId : crtActivity.getBrandIds()) {
                Brand s = (Brand) brandService.findById(brandId);
                if (null != s) {
                    u.getBrands().add(s);
                }
            }
        }
        if (null != crtActivity.getHairdresserId() && 0 < crtActivity.getHairdresserId()) {
            Hairdresser h = (Hairdresser) hairdresserService.findById(crtActivity.getHairdresserId());
            if (null != h) {
                u.setHairdresser(h);
            }
        }
        u.setStatus(crtActivity.getStatus());
        if (null == u.getId())
            activityService.add(u);
        else
            activityService.update(u);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }
    
    @ApiIgnore()
    @ApiOperation(value="删除活动", notes="根据URI的id来指定删除对象")
    @ApiImplicitParam(name = "id", value = "活动ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
    public ResultMsg delete(@PathVariable Integer id) {
        activityService.delete(id);
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }
    
    @ApiOperation(value="删除活动", notes="根据POST的id列表来指定删除对象，可批量")
    @ApiImplicitParam(name = "ids", value = "活动ID集", required = true, dataType = "Ids")
    @RequestMapping(value="/delete", method=RequestMethod.DELETE)
    public ResultMsg Batchdelete(@RequestBody Ids ids) {
        activityService.delete(ids.getIds());
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }

    @ApiIgnore()
    @ApiOperation(value="更新活动详细信息", notes="根据URI的id来指定更新对象，并根据传过来的activity信息来更新活动详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "活动ID", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "activity", value = "待更新的活动详细实体activity", required = true, dataType = "Activity")
    })
    @RequestMapping(value="/{id}", method=RequestMethod.PUT)
    public ResultMsg update(@PathVariable Integer id, @RequestBody Activity activity) throws DataNotFoundException {
        Activity u = (Activity) activityService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Activity.class.getName());
        }
        activity.setId(id);
        activityService.update(activity);
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }

    @ApiIgnore()
    @ApiOperation(value="获取活动详细信息", notes="根据URI的id来获取活动详细信息")
    @ApiImplicitParam(name = "id", value = "活动ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value="/{id}", method=RequestMethod.GET)
    public Activity load(@PathVariable Integer id) throws DataNotFoundException {
        Activity u = (Activity) activityService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Activity.class.getName());
        }
        u.setRemainder(u.getCount() - u.getCoupons().size());
        for (Image i : u.getImages()) {
            u.getImageIds().add(i.getId());
        }
        for (Brand i : u.getBrands()) {
            u.getBrandIds().add(i.getId());
        }
        for (Shop i : u.getShops()) {
            u.getShopIds().add(i.getId());
        }
        for (Item i : u.getItems()) {
            u.getItemIds().add(i.getId());
        }
        return u;
    }

    @ApiOperation(value="获取活动列表(适应客户端获取)", notes="根据提交的分页信息列出所以活动信息")
    @ApiImplicitParam(name = "pageConf", value = "分页信息实体", required = true, dataType = "PageConf")
    @RequestMapping(value={"/list"}, method=RequestMethod.POST)
    public MapList<Activity> list(@RequestBody PageConf pageConf) {
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        User user = (User) userService.findById(xmUser.getUserid());
        if (!Base.isValid(user) || Datalevel.NORMAL != user.getDatalevel()) {
            throw new AccessDeniedException("无效令牌信息，查无用户信息");
        }
        List<Activity> u = null;
        Long allCount = null;
        Object o = activityService.findAllByPage(pageConf);
        if (o instanceof Page) {
            allCount = ((Page<Activity>) o).getTotalElements();
            u = ((Page<Activity>) o).getContent();
        } else {
            allCount = (long) ((List<Activity>) o).size();
            u = (List<Activity>) o;
        }
        for (Activity c : u) {
            if (null != c.getCount() && null != c.getCoupons()) {
                c.setRemainder(c.getCount() - c.getCoupons().size());
            } else {
                c.setRemainder(0);
            }
            for (Image i : c.getImages()) {
                c.getImageIds().add(i.getId());
            }
            for (Shop s : c.getShops()) {
                c.getShopIds().add(s.getId());
                c.getShopNames().add(s.getName());
            }
            for (Item i : c.getItems()) {
                c.getItemIds().add(i.getId());
                c.getItemNames().add(i.getName());
            }
            for (Brand i : c.getBrands()) {
                c.getBrandIds().add(i.getId());
                c.getBrandNames().add(i.getName());
            }
            if (null != c.getHairdresser()) {
                c.setHairdresserId(c.getHairdresser().getId());
                c.setHairdresserName(c.getHairdresser().getName());
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("userid", user.getId());
            map.put("activityid", c.getId());
            List<Coupon> l = (List<Coupon>) couponService.findAllByPage(null, map);
            if (null != l && !l.isEmpty())
                c.setHold(true);
            else
                c.setHold(false);
        }
        return new MapList<Activity>(allCount, u);
    }

    // --------------------- 业务具体接口 ---------------------

    @ApiOperation(value = "客户端：领取优惠活动券", notes = "客户端客户对优惠活动进行优惠券领取")
    @ApiImplicitParam(name = "id", value = "优惠活动ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public ResultMsg getCoupon(@PathVariable @NotNull @Min(1) Integer id)
            throws RequestParamterException {
        Date now = new Date();
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        User user = (User) userService.findById(xmUser.getUserid());
        if (!Base.isValid(user) || Datalevel.NORMAL != user.getDatalevel()) {
            throw new AccessDeniedException("无效令牌信息，查无用户信息");
        }
        Activity c = (Activity) activityService.findById(id);
        if (!(Base.isValid(c) && c.getDatalevel() == Datalevel.NORMAL && c.getDeadline().getTime() > now.getTime()))
            throw new RequestParamterException("无效优惠活动");
        if (1 > (c.getCount() - c.getCoupons().size())) {
            throw new RequestParamterException("抱歉！此优惠活动已无优惠券可领取");
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userid", user.getId());
        map.put("activityid", c.getId());
        List<Coupon> l = (List<Coupon>) couponService.findAllByPage(null, map);
        if (null != l && !l.isEmpty())
            throw new RequestParamterException("已经领取过，不需要重复领取");
        Coupon coupon = new Coupon();
        coupon.setActivity(c);
        coupon.setUser(user);
        coupon.setUserName(user.getName());
        coupon.setName(c.getName());
        coupon.setCouponnum(idBitWorker.nextCouponNum());
        coupon.setStatus(CouponStatus.NORMAL);
        couponService.add(coupon);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @Transactional
    @ApiOperation(value = "发型师端：发型师发放优惠券", notes = "发型师可选择要发放的优惠活动券给指定的多个粉丝用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "优惠活动ID", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "ids", value = "用户ID集", required = true, paramType = "body", dataType = "Ids") })
    @RequestMapping(value = "/send/{id}", method = RequestMethod.POST)
    public ResultMsg sendCoupon(@PathVariable @NotNull @Min(1) Integer id, @RequestBody @NotNull Ids ids)
            throws RequestParamterException {
        if (null == ids.getIds() || ids.getIds().isEmpty())
            throw new RequestParamterException("请选择用户！");
        Date now = new Date();
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        User user = (User) userService.findById(xmUser.getUserid());
        if (!Base.isValid(user) || Datalevel.NORMAL != user.getDatalevel())
            throw new AccessDeniedException("无效令牌信息，查无用户信息");
        if (0 == xmUser.getHairdresserid()) {
            throw new RequestParamterException("当前用户非发型师用户，查无发型师信息");
        }
        Activity c = (Activity) activityService.findById(id);
        if (!(Base.isValid(c) && c.getDatalevel() == Datalevel.NORMAL && c.getDeadline().getTime() > now.getTime()))
            throw new RequestParamterException("无效优惠活动");
        if (ids.getIds().size() > (c.getCount() - c.getCoupons().size())) {
            throw new RequestParamterException("抱歉！此优惠活动下剩余优惠券不够分发");
        }
        if (null == c.getHairdresser() || c.getHairdresser().getId() != xmUser.getHairdresserid())
            throw new RequestParamterException("抱歉！此优惠活动非此发型师的优惠活动");
        for (Integer userId : ids.getIds()) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("userid", userId);
            map.put("activityid", c.getId());
            List<Coupon> l = (List<Coupon>) couponService.findAllByPage(null, map);
            if (null != l && !l.isEmpty())
                throw new RequestParamterException("存在已领取过优惠券的用户，不需要重复领取");
        }
        for (Integer userId : ids.getIds()) {
            User ur = (User) userService.findById(userId);
            if (Base.isValid(ur)) {
                Coupon coupon = new Coupon();
                coupon.setActivity(c);
                coupon.setUser(ur);
                coupon.setUserName(ur.getName());
                coupon.setName(c.getName());
                coupon.setCouponnum(idBitWorker.nextCouponNum());
                coupon.setStatus(CouponStatus.NORMAL);
                couponService.add(coupon);
            }
        }
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }
    
}
